﻿#region System Namespace
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.IO;
using System.Threading;
#endregion System Namespace

#region Foreign Namespace
using AIMLbot;
#endregion Foreign Namespace

#region Styx Namespace
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.Plugins;
#endregion Styx Namespace

namespace AIMLBattleground1
{
    public class Response
    {
        public readonly string User;
        public readonly string Message;

        public Response(string userName, string message)
        {
            User = userName;
            Message = message;
        }
    }

    public class AIMLBattleground : HBPlugin
    {
        private Bot _aimlBot;
        private List<Response> _responseList;
        private List<User> _userList;

        public string NameOfPlugin = "AIMLBattleground";
        public string DoubleDash = "\\";
        public string DashRight = "/";
        public string IgnoreListPath = "Plugins" + "\\" + "AIMLBattleground" + "\\" + "ignore" + "\\";
        public string MainPath = "Plugins" + "\\" + "AIMLBattleground" + "\\" + "logs" + "\\";
        public string DayShort = String.Format("{0:dd}", DateTime.Now.DayOfWeek.ToString());
        public string Month = String.Format("{0:mmmm}", DateTime.Now.Month.ToString());
        public string Day = String.Format("{0:dddd}", DateTime.Now.Day.ToString());
        public string Year = String.Format("{0:yyyy}", DateTime.Now.Year.ToString());
        public char[] CharsToTrim = { '.' };

        public override string Name { get { return "AIMLBattleground"; } }
        public override string Author { get { return "Giwin"; } }
        public override Version Version { get { return new Version(1, 3); } }
        public override bool WantButton { get { return true; } }
        public override void OnButtonPress() { new Form1().ShowDialog(); }

        public override void Initialize()
        {
            Logging.Write("[" + Name + "]: " + Version + " " + "Loaded");
            Chat.Battleground += WoWChatBattleground; // Hook event
            Chat.BattlegroundLeader += WoWChatBattleground; // Hook event
            FileChecker();
            UpdateCharacterNameInAimlFiles();
            _aimlBot = new Bot();
            _aimlBot.loadSettings();
            _aimlBot.loadAIMLFromFiles();
            _userList = new List<User>();
            _responseList = new List<Response>();
        }

        public void WoWChatBattleground(Chat.ChatSimpleMessageEventArgs e)
        {
            User user = _userList.Find(o => o.UserID == e.Args[1].ToString());

            user = new User(e.Args[1].ToString(), _aimlBot);
            _userList.Add(user);

            Result result = _aimlBot.Chat(new Request(e.Message, user, _aimlBot));

            if (_responseList.Contains(new Response(user.UserID, result.Output))) return;
            if (e.Args[1].ToString() == StyxWoW.Me.Name || e.Args[0].ToString() == "") return;
            _responseList.Add(new Response(user.UserID, result.Output));

            if (!File.Exists(MainPath + DoubleDash + Year + DoubleDash + Month +
                             DoubleDash + DayShort +
                             DoubleDash + Day + ".txt"))
            {
                if (File.Exists(MainPath + DoubleDash + Year + DoubleDash + Month +
                                DoubleDash + DayShort +
                                DoubleDash + Day + ".txt")) return;
                FileChecker();
            }
            else
            {
                using (StreamWriter writer = File.AppendText(MainPath + Year + DoubleDash + Month +
                                                          DoubleDash + DayShort +
                                                          DoubleDash + Day + ".txt"))
                {
                    var received = "," + string.Format("Time: {0} | Author: {1} | Message Received: {2}",
                                                 DateTime.Now.ToLongTimeString(), e.Args[1], e.Args[0]);
                    var sent = "," + string.Format("Time: {0} | Author: {1} | Message Sent: {2}",
                                             DateTime.Now.ToLongTimeString(), e.Args[1],
                                             result.Output.TrimEnd(CharsToTrim));

                    Logging.Write(received.Remove(0, 1));
                    writer.WriteLine(received);
                    writer.WriteLine(received.Remove(received.Length));

                    Logging.Write(sent.Remove(0, 1));
                    writer.WriteLine(sent);
                }
            }
        }

        public void UpdateCharacterNameInAimlFiles()
        {
            try
            {
                using (StreamReader read = new StreamReader("Plugins" + "\\" + "AIMLBattleground" + "\\" + "aiml" + "\\" +
                                         "AIMLBattleground_bot.aiml"))
                {
                    var contents = read.ReadToEnd();
                    if (contents.Contains(StyxWoW.Me.Name.ToUpper()))
                        Logging.Write("[" + NameOfPlugin + "]:" +
                                      " Congratulations, your aiml files contains one or more of your current character's name");
                    else if (contents.Contains("YOURCHARACTERNAME"))
                        Logging.Write("[" + NameOfPlugin + "]: " +
                                      "[WARNING]: Please update AIMLBattleground.aiml by replacing 'YOURCHARACTERNAME' with your character's name (use Notepad and press CTRL + H, takes 2 seconds instead of 2 hours)");
                    else
                        Logging.Write("[" + NameOfPlugin + "]: " +
                                      "[WARNING]: Please update AIMLBattleground.aiml, your current character's name doesn't reflect inside the aiml file");
                }
            }
            catch (Exception e)
            {
                Debug.Assert(e.Message != null, "e.Message != null");
                Logging.Write(e.Message);
            }
        }

        public void FileChecker()
        {
            if (!File.Exists(MainPath + DoubleDash + Year + DoubleDash + Month + DoubleDash + DayShort))
            {
                Logging.Write("[" + NameOfPlugin + "]: " + "File Created - " + Year + DashRight + Month + DashRight + DayShort);
                File.Create(MainPath + DoubleDash + Year + DoubleDash + Month + DoubleDash + DayShort + DoubleDash + Day);
            }
        } 
        private void TrySend(Response response)
        {
            if (_responseList.Count > 0 && !string.IsNullOrEmpty(response.Message) &&
                response.Message.TrimEnd(CharsToTrim) != null && response.Message.TrimEnd(CharsToTrim) != "" &&
                response.Message.TrimEnd(CharsToTrim) != " ")
            {
                Thread.Sleep(new Random().Next(4794, 7639));

                Logging.Write("Author: " + response.User.ToString() + " | " + "Message Sent: " +
                              response.Message.TrimEnd(CharsToTrim));

                using (StreamWriter writer = File.AppendText(IgnoreListPath + "ignoreList.txt"))
                {
                    var author = string.Format("{0} | {1},", response.User, response.Message.TrimEnd(CharsToTrim));
                    writer.WriteLine(author);
                }
                Styx.WoWInternals.Lua.DoString(String.Format(
                    "SendChatMessage(\"{0}\", \"Battleground\", nil, \"{1}\");",
                    response.Message.TrimEnd(CharsToTrim),
                    response.User));
                _responseList.Clear();
            }
        }
        public override void Pulse()
        {
            if (StyxWoW.Me == null || !StyxWoW.Me.IsAlive || !StyxWoW.IsInGame || !StyxWoW.IsInWorld) return;

            if (_responseList != null && _responseList.Count != 0)
            {
                TrySend(_responseList.First());
            }
        }
    }
}
